#include <stdio.h>
#include <stdlib.h>
#include "dsa/list.h"

// 测试节点结构
struct test_node
{
    int data;
    struct list_head list;
};

// 创建节点（简化辅助）
struct test_node *new_node(int data)
{
    struct test_node *node = malloc(sizeof(*node));
    node->data = data;
    INIT_LIST_HEAD(&node->list);
    return node;
}

// 打印整个链表
void print_list(struct list_head *head)
{
    printf("list: ");
    struct test_node *pos;
    list_for_each_entry(pos, head, list)
    {
        printf("%d ", pos->data);
    }
    printf("\n");
}

int main(void)
{
    // 定义并初始化链表头
    LIST_HEAD(mylist);

    printf("=== Simple Linux Kernel List Test ===\n");

    // 1. 插入几个节点（头插）
    struct test_node *n1 = new_node(1);
    struct test_node *n2 = new_node(2);
    struct test_node *n3 = new_node(3);

    list_add_tail(&n1->list, &mylist); // 尾插 1
    list_add_tail(&n2->list, &mylist); // 尾插 2
    list_add(&n3->list, &mylist);      // 头插 3

    printf("After insert 1,2,3: ");
    print_list(&mylist); // 输出: 3 1 2

    // 2. 遍历并查找
    printf("Traversal: ");
    struct test_node *pos;
    list_for_each_entry(pos, &mylist, list)
    {
        printf("%d ", pos->data);
    }
    printf("\n");

    // 3. 删除节点 n1 (data=1)
    printf("Deleting node with data=1...\n");
    list_del(&n1->list);
    free(n1);
    printf("After delete 1: ");
    print_list(&mylist); // 输出: 3 2

    // 4. 替换 n2 为新节点 n4
    struct test_node *n4 = new_node(4);
    printf("Replacing node 2 with 4...\n");
    list_replace(&n2->list, &n4->list);
    list_del(&n2->list);
    free(n2);
    printf("After replace: ");
    print_list(&mylist); // 输出: 3 4

    // 5. 再插入一个尾部节点
    struct test_node *n5 = new_node(5);
    list_add_tail(&n5->list, &mylist);
    printf("After add tail 5: ");
    print_list(&mylist); // 输出: 3 4 5

    // 6. 最后清空释放
    printf("Cleaning up...\n");
    struct test_node *tmp;
    list_for_each_entry_safe(pos, tmp, &mylist, list)
    {
        list_del(&pos->list);
        free(pos);
    }

    printf("All done. List is empty: %s\n", list_empty(&mylist) ? "yes" : "no");

    return 0;
}